<template>
  <div ref="cusEditor"  :style="eheight"></div>
</template>
<script setup lang="ts">
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { withDefaults, defineProps, ref, defineEmits, onMounted, onUnmounted, watch, nextTick } from 'vue'
import './worker'
import { useDebounceEffect } from '../../hooks/useDebounceEffect';



interface IProps {
  modelValue: string
  disabled?: boolean
  eheight: string
  minimap: boolean
  constModelData: string[]
  editorConfig: { language: string; theme: string }
}
const props = withDefaults(defineProps<IProps>(), {
  modelValue: '',
  disabled: false,
  eheight:"height: 300px",
  minimap: false,
  constModelData: () => [],
  editorConfig: () => ({ language: 'sql', theme: 'vs-dark' }),
})


const content = ref<string | undefined>("");
const cusEditor = ref<HTMLElement | null>(null)
let editor: Partial<monaco.editor.IStandaloneCodeEditor> = {}
const emit = defineEmits(['update:modelValue'])
/**初始化编辑器 */
onMounted(() => {
  onDispose()
  if (cusEditor.value) {
    editor = monaco.editor.create(cusEditor.value, { 
        value: props.modelValue || '', // 初始显示文字
        lineNumbers: 'on', // 是否展示行号 'off' | 'on
        automaticLayout: true, // 自适应布局 默认true
        minimap: {
            enabled: props.minimap,
        },
        tabSize: 2,
         // 禁用默认右键菜单
        contextmenu: false,
        fontSize: 16
        , ...props.editorConfig, readOnly: props.disabled })
    editor.onDidChangeModelContent &&
      editor.onDidChangeModelContent(() => {
        const value = editor.getValue && editor.getValue() // 给父组件实时返回最新文本
        content.value = value;
        emit('update:modelValue', value)
      })
  }
    // 需要等待 DOM 更新
  nextTick(async () => {

      // 添加 50ms 延迟确保窗口完全渲染
      setTimeout(() => {
          cusEditor.value?.focus()
      }, 50)
  })
})
/**销毁实例 */
const onDispose = () => {
  editor && editor.dispose && editor.dispose()
}
onUnmounted(() => {
  onDispose()
})
/**修改只读状态 */
watch(
  () => props.disabled,
  (val) => {
    editor.updateOptions && editor.updateOptions({ readOnly: val })
  }
)
/**修改配置 */
watch(
  () => props.editorConfig,
  (val) => {
    const model = editor.getModel && editor.getModel()
    if (model) {
      monaco.editor.setModelLanguage(model, val.language)
      monaco.editor.setTheme(val.theme)
    }
  },
  { deep: true }
)
/**回显数据 */
watch(
  () => props.modelValue,
  (val) => {
    if (editor) {
      const value = editor.getValue && editor.getValue()
      if (val !== value) {
        editor.setValue && editor.setValue(val || '')
      }
    }
  }
)

// 把 invoke 的逻辑放到这里
useDebounceEffect(content, (val) => {
  if (val) {
    const langId = detectByContent(val); // 自定义内容检测函数，返回语言 ID
    const model = editor.getModel && editor.getModel()
    if (model) {
      console.log("----" + langId)
      monaco.editor.setModelLanguage(model, langId)
    }
  }

}, 800)  // 800 ms 防抖


function detectByContent(code: string): string {
  const t = code.trim();
  // HTML 优先，常用 html 标签
  if (/^<(!doctype|html|head|body|div|span|script|style|[a-z]+\s)/i.test(t))
    return 'html';
  // XML，要求有 <?xml 或自定义标签，并且排除 html 关键词
  if (
    /^<\?xml\s/.test(t) ||
    (/^<([a-zA-Z0-9]+)(\s|>)/.test(t) &&
      !/^<(html|head|body|div|span|script|style)/i.test(t))
  ) {
    return 'xml';
  }
  // JSON
  if (/^(?:\{[\s\S]*\}|\[[\s\S]*\])$/.test(t))
    return 'json';
  // YAML，且排除 < 开头
  if (!t.startsWith("<") && (/^---/.test(t) || /^[\w\-]+\s*:\s*.+/m.test(t))) {
    return 'yaml';
  }
  // Markdown
  if (/^#+\s+/m.test(t) || /\[[^\]]+\]\([^)]+\)/.test(t))
    return 'markdown';
  // SQL
  if (
    /\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|TRUNCATE|FROM|WHERE|JOIN)\b/i.test(t)
  ) {
    return 'sql';
  }
  // JavaScript
  if (/;\s*$/.test(t) || /\bfunction\b/.test(t))
    return 'javascript';
  // TypeScript
  if (/\:\s*string\b/.test(t) || /\binterface\b/.test(t))
    return 'typescript';
  // CSS
  if (/^[\w-]+\s*\{[\s\S]*\}/.test(t))
    return 'css';
  // fallback
  return 'javascript';
}



</script>
